﻿using Microsoft.Extensions.DependencyInjection;
using Puppy.Actor;
using Puppy.ActorDb;
using System;
using System.Collections.ObjectModel;
using Volo.Abp;
using Volo.Abp.Autofac;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.Modularity;

namespace Puppy.Scheduler
{
    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(PuppyActorModule)
    )]
    public class SchedulerServerModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddHostedService<ServerHostedService>();

            var connStr = Guid.NewGuid().ToString();

            Configure<AbpDbConnectionOptions>(options =>
            {
                options.ConnectionStrings.Default = connStr;
            });

            context.Services.AddActorDbContext<DemoActorDbContext>(options =>
            {
                options.AddDefaultRepositories(includeAllEntities: true);
            });
        }
    }

    public class DemoActorDbContext : ActorDbContext
    {
        public IActorSet<Person> People { get; set; }

        public IActorSet<Phone> Phones { get; set; }
    }

    public class Person : FullAuditedEntity<Guid>
    {
        public virtual Guid? TenantId { get; set; }

        public virtual Guid? CityId { get; set; }

        public virtual string Name { get; private set; }

        public virtual int Age { get; set; }

        public virtual DateTime? Birthday { get; set; }

        public virtual DateTime? LastActive { get; set; }

        public virtual Collection<Phone> Phones { get; set; }

        public Person()
        {

        }

        public Person(Guid id, string name, int age, Guid? tenantId = null, Guid? cityId = null)
            : base(id)
        {
            Name = name;
            Age = age;
            TenantId = tenantId;
            CityId = cityId;

            Phones = new Collection<Phone>();
        }

        public virtual void ChangeName(string name)
        {
            Check.NotNullOrWhiteSpace(name, nameof(name));

            var oldName = Name;
            Name = name;
        }
    }

    public class Phone : AuditedEntity<Guid>
    {
        public virtual Guid PersonId { get; set; }

        public virtual string Number { get; set; }

        public virtual PhoneType Type { get; set; }

        public Phone()
        {

        }

        public Phone(Guid personId, string number, PhoneType type = PhoneType.Mobile)
        {
            Id = Guid.NewGuid();
            PersonId = personId;
            Number = number;
            Type = type;
        }

        public override object[] GetKeys()
        {
            return new object[] { PersonId, Number };
        }
    }

    public enum PhoneType
    {
        Mobile,
        Home,
        Office
    }

    public class PersonActor : PuppyActor<Person>
    {
        public PersonActor()
        {

        }
    }
}
